using System;
using System.Collections.Generic;
using System.Text;
using Zoo.DAL;
using SubSonic;
using Zoo;
using System.Data;
using System.Web.UI.WebControls;
using System.Diagnostics;
using System.IO;
using System.Configuration;
using Zoo.Domain;

namespace Zoo
{
    public class ZooModel:IZooModel
    {

        public int GetUserID(string login, string password)
        {
            StoredProcedure sp = SPs.SpGetUserID(login, password);
            return Convert.ToInt32(sp.ExecuteScalar());
        }

        public System.Collections.Specialized.StringDictionary CreateDictionary(string language)
        {
            //Preconditions
            Debug.Assert(language!=null,"Precondition assertion failed, ZooModel.CreateDictionary language was null");
            Debug.Assert(language.Length>1, "Precondition assertion failed, ZooModel.CreateDictionary language length was <2");

            //Implementation
            System.Collections.Specialized.StringDictionary stringDico = new System.Collections.Specialized.StringDictionary();
            IDataReader rdr = SPs.SpGetDictionary().GetReader();
            try
            {
                while (rdr.Read())
                {
                    stringDico.Add(
                        rdr["DictionaryKey"].ToString().ToLower().Trim(),
                        rdr[language].ToString());
                }
            }
            catch
            {
                throw;
            }
            finally
            {
                rdr.Close();
            }

            //Postconditions
            Debug.Assert(stringDico.Count > 0, "PostCondition assertion failed, ZooModel.CreateDictionary stringDico was empty");

            return stringDico;
        }

        public System.Web.UI.WebControls.ListItemCollection GetCountryList(Dictionary currentDictionary)
        {
            //Preconditions
            Debug.Assert(currentDictionary != null, "Preconditionerror, ZooModel.GetCountryList assert false, currentDictionary is Null");

            //Implementation
            System.Web.UI.WebControls.ListItemCollection returnValue = new System.Web.UI.WebControls.ListItemCollection();
            DAL.CountryCollection countrys = new CountryCollection();
            countrys.Load();
            foreach (Country country in countrys)
            {
                returnValue.Add(new ListItem(currentDictionary[country.CountryName],country.CountryID.ToString()));
            }

            //PostConditions
            Debug.Assert(returnValue.Count>0 , "Postcondition, GetCountryList return value is empty!");

            return returnValue;
        }

        public System.Web.UI.WebControls.ListItemCollection GetRegionList(string countryValue, Dictionary currentDictionary)
        {
            //Preconditions 
            int countryID;
            Debug.Assert(int.TryParse(countryValue,out countryID),"Precondition error, ZooModel.GetRegionList assert false countryValue could not be parsed as int" );
            Debug.Assert(currentDictionary != null,"Preconditionerror, ZooModel.GetCountryList assert false, currentDictionary is Null");

            //Implementation
            System.Web.UI.WebControls.ListItemCollection returnValue = new System.Web.UI.WebControls.ListItemCollection();
            DAL.RegionCollection regions = new RegionCollection().Where("CountryID", countryID).Load();
            
            foreach (Region region in regions)
            {
                returnValue.Add(new ListItem(currentDictionary[region.RegionName],region.RegionID.ToString()));
            }
            
            //PostConditions
            Debug.Assert(returnValue.Count>0, "Postcondition assertion failed, ZooModel.GetRegionist returnValue was empty");
            return returnValue;

            
        }

        public void Register(
            string language, 
            string nickName, 
            string emailAddress, 
            string gender, 
            string seeking, 
            int countryID, 
            int regionID, 
            DateTime bornDate,
            string city,
            string description,
            string password,
            bool emailOptin,
            byte[] pictureContent,
            IPictureStorage pictureStorage)
        {
            //Precondition
            Debug.Assert(!Utility.IsEmpty(language), "ZooModel Register precondition assertion failed: language was empty!");
            Debug.Assert(!Utility.IsEmpty(nickName), "ZooModel Register precondition assertion failed: nickName was empty!");
            Debug.Assert(!Utility.IsEmpty(emailAddress), "ZooModel Register precondition assertion failed: emailAddress was empty!");
            Debug.Assert(!Utility.IsEmpty(gender), "ZooModel Register precondition assertion failed: gender was empty!");
            Debug.Assert(!Utility.IsEmpty(seeking), "ZooModel Register precondition assertion failed: seeking was empty!");
            Debug.Assert(!Utility.IsNull(bornDate), "ZooModel Register precondition assertion failed: bornDate was null!");
            Debug.Assert(!Utility.IsEmpty(city), "ZooModel Register precondition assertion failed: city was empty!");
            Debug.Assert(!Utility.IsEmpty(description), "ZooModel Register precondition assertion failed: description was empty!");
            Debug.Assert(!Utility.IsEmpty(password), "ZooModel Register precondition assertion failed: password was empty!");
            Debug.Assert(pictureContent.Length > 0, "PictureContent Length was 0, image was not present!");

            ZooUser user = new ZooUser();
            Picture registrationPicture = new Picture();
            try
            { 
                user.BornDate = bornDate;
                user.City = city;
                user.CountryID = countryID;
                user.Description = description;
                user.EmailAddress = emailAddress;
                user.EmailOptin = emailOptin;
                user.Gender = gender;
                user.LastLogin = DateTime.Now;
                user.NickName = nickName;
                user.Online = true;
                user.RegionID = regionID;
                user.Password = password;
                user.Seeking = seeking;
                user.UserLanguage = language;
                user.Save();

                registrationPicture.PictureIndex = 0;
                registrationPicture.PictureTitle = user.NickName;
                registrationPicture.PictureDescription = "";
                registrationPicture.UserID = user.UserID;
                registrationPicture.Save();  
                int imageHeight=Convert.ToInt32(ConfigurationManager.AppSettings["ImageHeight"]); 
                pictureStorage.Save(pictureContent, registrationPicture.PictureID, imageHeight);
            }
            catch
            {
                //Cleanup
                pictureStorage.Delete(registrationPicture.PictureID);
                if (registrationPicture.PictureID>0)
                    Picture.Delete(registrationPicture.PictureID);
                if (user.UserID > 0)
                    ZooUser.Delete(user.UserID);

                throw;
                
            }
           

            //PostCondition
            Debug.Assert(user.UserID>0, "ZooModel.Register postcondition assertion failed: user was not saved!");
        }

        public bool UserExist(string nickName)
        {
            Zoo.DAL.ZooUser user = new ZooUser();
            user.LoadByParam("NickName", nickName);
            return user.UserID > 0;
        }

        public IdentityCard[] GetNewUsers(string language)
        {

            IDataReader newUserRows = SPs.SpGetNewUsers(language).GetReader();
            ZooUserCollection newUsers = new ZooUserCollection();
            newUsers.Load(newUserRows);

            return Mappers.UserMapper.ToUserIdentityCards(newUsers);
        }

        public IdentityCard GetUserDetail(int userID)
        {
            ZooUser user = new ZooUser(userID);
            return Zoo.Mappers.UserMapper.ToIdentityCard(user);
        }



        public IdentityCard[] FindUsers(string[] languages, int ageMax, int ageMin, string city, string gender, int countryID, int regionID, string seeking)
        {
            Query query = new Query("ZooUsers");
            foreach (string lang in languages)
            {
                query.OR("UserLanguage", lang);
            }
            IDataReader reader = ZooUser.FetchByQuery(query);
            ZooUserCollection usersFound = new ZooUserCollection();
            usersFound.Load(reader);
            return Zoo.Mappers.UserMapper.ToUserIdentityCards(usersFound);
        }

    }
}
